﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Linq;
using System.Globalization;
using System.IO;

namespace XML
{
    class MainXML
    {
        public static void ArtistsAndAlbumsCountDOM()
        {
            XmlDocument doc = new XmlDocument();
            doc.Load("../../catalog.xml");
            XmlNode root = doc.DocumentElement;
            Dictionary<string, int> artists = new Dictionary<string, int>();
            foreach (XmlNode node in root.ChildNodes)
            {
                string artist = node["artist"].InnerText;
                if (artists.ContainsKey(artist))
                {
                    artists[artist]++;
                }
                else
                {
                    artists.Add(artist, 1);
                }
            }
            foreach (var artist in artists)
            {
                Console.WriteLine("{0} have {1} albums.", artist.Key, artist.Value);
            }
        }
        public static void ArtistsAndAlbumsCountXPATH()
        {
            XmlDocument doc = new XmlDocument();
            doc.Load("../../catalog.xml");
            string xPathQuery = "/albums/album/artist";

            XmlNodeList allArtists = doc.SelectNodes(xPathQuery);
            Dictionary<string, int> artists = new Dictionary<string, int>();
            foreach (XmlNode art in allArtists)
            {
                string artist = art.InnerText;
                if (artists.ContainsKey(artist))
                {
                    artists[artist]++;
                }
                else
                {
                    artists.Add(artist, 1);
                }
            }
            foreach (var artist in artists)
            {
                Console.WriteLine("{0} have {1} albums.", artist.Key, artist.Value);
            }
        }
        public static void RemoveExpensiveAlbums()
        {
            XmlDocument doc = new XmlDocument();
            doc.Load("../../catalog.xml");

            XmlNode root = doc.DocumentElement;
            List<XmlNode> nodesToDel = new List<XmlNode>();
            foreach (XmlNode node in root.ChildNodes)
            {
                if (Convert.ToDecimal(node["price"].InnerText) > 20.0m)
                {
                    nodesToDel.Add(node);
                }
            }

            foreach (var node in nodesToDel)
            {
                root.RemoveChild(node);
            }

            doc.Save("../../catalog.xml");
        }
        public static void SongsTitles()
        {
            XmlReader reader = XmlReader.Create("../../catalog.xml");
            using (reader)
            {
                while (reader.Read())
                {
                    if (reader.NodeType == XmlNodeType.Element &&
                        reader.Name == "title")
                    {
                        Console.WriteLine(reader.ReadElementString());
                    }
                }
            }
        }
        public static void SongsTitlesXDoc()
        {
            XDocument doc = XDocument.Load("../../catalog.xml");

            var titles =
                from song in doc.Descendants("song")
                select new { song.Element("title").Value };

            foreach (var title in titles)
            {
                Console.WriteLine(title.Value);
            }
        }
        public static void CreateAlbums()
        {
            XmlReader reader = XmlReader.Create("../../catalog.xml");
            using (reader)
            {
                XmlTextWriter writer = new XmlTextWriter("../../albums.xml", UTF8Encoding.UTF8);
                using (writer)
                {
                    writer.Formatting = Formatting.Indented;
                    writer.IndentChar = '\t';
                    writer.Indentation = 1;

                    writer.WriteStartDocument();
                    writer.WriteStartElement("albums");
                    while (reader.Read())
                    {
                        if (reader.NodeType == XmlNodeType.Element &&
                            reader.Name == "album")
                        {
                            string name = "";
                            string author = "";
                            XmlReader innerReader = reader.ReadSubtree();
                            while (innerReader.Read())
                            {
                                if (innerReader.NodeType == XmlNodeType.Element &&
                                   innerReader.Name == "name")
                                {
                                    name = innerReader.ReadElementString();
                                }
                                if (innerReader.NodeType == XmlNodeType.Element &&
                                   innerReader.Name == "artist")
                                {
                                    author = innerReader.ReadElementString();
                                }
                            }
                            writer.WriteStartElement("album");
                            writer.WriteAttributeString("author", author);
                            writer.WriteValue(name);
                            writer.WriteEndElement();
                        }
                    }
                    writer.WriteEndDocument();
                }
            }
        }
        public static void CreatePersons()
        {
            XmlDocument doc = new XmlDocument();
            XmlDeclaration decl = doc.CreateXmlDeclaration("1.0", "utf-8", null);
            XmlElement root = doc.CreateElement("persons");
            doc.InsertBefore(decl, doc.DocumentElement);
            doc.AppendChild(root);

            string answ = "y";
            while (answ != "n")
            {
                XmlElement parentNode = doc.CreateElement("person");
                doc.DocumentElement.AppendChild(parentNode);
                Console.Write("Name: ");
                string name = Console.ReadLine();
                Console.Write("Address: ");
                string address = Console.ReadLine();
                Console.Write("Phone: ");
                string phone = Console.ReadLine();
                XmlElement xmlName = doc.CreateElement("name");
                XmlElement xmlAddress = doc.CreateElement("address");
                XmlElement xmlPhone = doc.CreateElement("phone");
                XmlText nameText = doc.CreateTextNode(name);
                XmlText addText = doc.CreateTextNode(address);
                XmlText phoneText = doc.CreateTextNode(phone);
                parentNode.AppendChild(xmlName);
                parentNode.AppendChild(xmlAddress);
                parentNode.AppendChild(xmlPhone);
                xmlName.AppendChild(nameText);
                xmlAddress.AppendChild(addText);
                xmlPhone.AppendChild(phoneText);
                Console.Write("Do you want to enter another peson(y/n)? ");
                answ = Console.ReadLine();
            }

            doc.Save("../../persons.xml");
        }
        
        public static void Dir()
        {
            string direct = @"C:\Program Files\Adobe";
            DirectoryInfo d = new DirectoryInfo(direct);
            XmlTextWriter writer = new XmlTextWriter("../../Directories.xml", Encoding.UTF8);
            using (writer)
            {
                writer.Formatting = Formatting.Indented;
                writer.IndentChar = '\t';
                writer.Indentation = 1;
                writer.WriteStartDocument();
                writer.WriteStartElement("directoriesAndFiles");

                CreateDir(d, writer);

                writer.WriteEndDocument();
            }
        }
        public static void CreateDir(DirectoryInfo d, XmlTextWriter writer)
        {
            writer.WriteStartElement("dir");
            writer.WriteAttributeString("name", d.Name);
            foreach (var file in d.GetFiles())
            {
                writer.WriteStartElement("file");
                writer.WriteAttributeString("extension", file.Extension);
                writer.WriteValue(file.Name);
                writer.WriteEndElement();
            }
            foreach (var dir in d.GetDirectories())
            {
                CreateDir(dir, writer);
            }
            writer.WriteEndElement();
        }

        public static void DirX()
        {
            XDocument doc = new XDocument(new XDeclaration("1.0", "utf-8", null),
                                            new XElement("directoriesAndFiles"));
            string direct = @"C:\VS";
            DirectoryInfo d = new DirectoryInfo(direct);
            CreateDirX(d, doc.Root);
            doc.Save("../../DirectoriesX.xml");
        }
        public static void CreateDirX(DirectoryInfo d, XElement doc)
        {
            XElement dir = new XElement("dir", new XAttribute("name", d.Name));
            doc.Add(dir);
            foreach (var file in d.GetFiles())
            {
                dir.Add(new XElement("file", file.Name, new XAttribute("extension", file.Extension)));
            }
            foreach (var d2 in d.GetDirectories())
            {
                CreateDirX(d2, dir);
            }
        }

        public static void Prices()
        {
            XmlDocument doc = new XmlDocument();
            doc.Load("../../catalog.xml");
            int date = DateTime.Now.AddYears(-5).Year;
            string xPathQuery = string.Format("/albums/album[year <= {0}]", date);
            XmlNodeList albums = doc.SelectNodes(xPathQuery);
            foreach (XmlNode node in albums)
            {
                Console.WriteLine(node["price"].InnerText);
            }

            Console.WriteLine();

            XDocument doc2 = XDocument.Load("../../catalog.xml");
            var res =
                from album in doc2.Descendants("album")
                where Convert.ToInt32(album.Element("year").Value) < date
                select new { album.Element("price").Value };

            foreach (var node in res)
            {
                Console.WriteLine(node.Value);
            }
        }

        static void Main()
        {
            Dir();
        }
    }
}
